package hn.sigit.dao.hnd.cadastre;

import hn.sigit.model.hnd.cadastre.HND_Parcel;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.hibernatespatial.criterion.SpatialRestrictions;

import com.vividsolutions.jts.geom.Polygon;

public class HND_ParcelDAO extends HND_SpatialZoneDAO {
	private static final long serialVersionUID = 1L;

	public static List<HND_Parcel> loadParcels() {
		return loadParcels(getSession());
	}
	public static HND_Parcel loadParcelById(long parcelId) {
		return loadParcelById(getSession(), parcelId);
	}
	public static List<HND_Parcel> loadParcelsByFieldTab(Long fieldTab) {
		return loadParcelsByFieldTab(getSession(), fieldTab);
	}
	public static List<HND_Parcel> loadParcelsByCadastralKey(String cadastralKey) {
		return loadParcelsByCadastralKey(getSession(), cadastralKey);
	}
	public static List<HND_Parcel> loadParcelsByMunicipalKey(String municipalKey) {
		return loadParcelsByMunicipalKey(getSession(), municipalKey);
	}
	public static List<HND_Parcel> loadNeighborsByHNDParcel(HND_Parcel hndParcel) {
		return loadNeighborsByHNDParcel(getSession(), hndParcel);
	}
	public static List<HND_Parcel> loadParcelPredecessors(HND_Parcel hndParcel) {
		return loadParcelPredecessors(getSession(), hndParcel);
	}
	public static List<HND_Parcel> loadParcelSuccessors(HND_Parcel hndParcel) {
		return loadParcelSuccessors(getSession(), hndParcel);
	}


	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcels(Session session) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		
		return (List<HND_Parcel>) criteria.list();
	}
	public static HND_Parcel loadParcelById(Session session, long parcelId) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("suID", parcelId));
		
		return (HND_Parcel) criteria.uniqueResult();
	}	
	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcelsByFieldTab(Session session, Long fieldTab) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("fieldTab", fieldTab));
		
		return (List<HND_Parcel>) criteria.list();
	}
	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcelsByCadastralKey(Session session, String cadastralKey) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("cadastralKey", cadastralKey));
		
		return (List<HND_Parcel>) criteria.list();
	}
	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcelsByMunicipalKey(Session session, String municipalKey) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("municipalKey", municipalKey));
		
		return (List<HND_Parcel>) criteria.list();
	}
	public static List<HND_Parcel> loadNeighborsByHNDParcel(Session session, HND_Parcel hndParcel) {
		Polygon filter = hndParcel.getShape();
		
		if (filter != null) {
			List<HND_Parcel> hndParcelList = new ArrayList<HND_Parcel>();
			
			Criteria criteria = session.createCriteria(HND_Parcel.class);
			criteria.add(SpatialRestrictions.touches("shape", filter));
			
			@SuppressWarnings("unchecked")
			List<HND_Parcel> hndTouchingParcelList = (List<HND_Parcel>)criteria.list();
			if (hndTouchingParcelList != null)
				for (HND_Parcel hndTouchingP : hndTouchingParcelList)
					//TODO: Parameterize if we want touching parcels with intersection > 0 included or not
					//if (hndTouchingP.getShape().intersection(filter).getLength() > 0.0001)
					hndParcelList.add(hndTouchingP);
			
			return hndParcelList;
		}
		
		return null;
	}
	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcelPredecessors(Session session, HND_Parcel hndParcel) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("endLifespanVersion", hndParcel.getBeginLifespanVersion()));
		
		return (List<HND_Parcel>) criteria.list();
	}
	@SuppressWarnings("unchecked")
	public static List<HND_Parcel> loadParcelSuccessors(Session session, HND_Parcel hndParcel) {
		Criteria criteria = session.createCriteria(HND_Parcel.class);
		criteria.add(Restrictions.eq("beginLifespanVersion", hndParcel.getEndLifespanVersion()));
		
		return (List<HND_Parcel>) criteria.list();
	}
}
